/**
 * 
 */
package com.zufangbao.earth.handler.impl;

import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.demo2do.core.persistence.GenericDaoSupport;
import com.demo2do.core.web.resolver.Page;
import com.zufangbao.earth.handler.ReceivableHandler;
import com.zufangbao.earth.service.AuthorisedBillSketchService;
import com.zufangbao.gluon.api.earth.ReceivablesBrief;
import com.zufangbao.gluon.api.quark.AuthorisedBillSketch;
import com.zufangbao.gluon.api.quark.TransactionRecordSketch;
import com.zufangbao.gluon.exception.CommonException;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth.ErrorCode4AutorisedBillSketch;
import com.zufangbao.gluon.spec.global.GlobalCodeSpec.GeneralErrorCode;
import com.zufangbao.sun.entity.company.corp.App;
import com.zufangbao.sun.entity.order.Order;
import com.zufangbao.sun.entity.order.TransactionRecordStatus;
import com.zufangbao.sun.entity.receivables.HistoryPaidType;
import com.zufangbao.sun.service.AppService;
import com.zufangbao.sun.service.OrderService;
import com.zufangbao.sun.service.TransactionRecordService;

/**
 * @author wukai
 *
 */
@Component("mercuryReceivableHandler")
public class MercuryReceivableHandlerImpl implements ReceivableHandler{

	@Autowired
	private OrderService orderService;
	
	@Autowired
	private AppService appService;
	
	@Autowired
	private GenericDaoSupport genericDaoSupport;
	
	@Autowired
	private TransactionRecordService transactionRecordService;
	
	@Autowired
	private AuthorisedBillSketchService authorisedBillSketchService;
	
	public static final Log logger = LogFactory.getLog(MercuryReceivableHandlerImpl.class);
	
	@Override
	public List<Order> getHistoryPaidOrder(String appId,
			String particalUniqueId, String contractNo,
			HistoryPaidType historyPaidType, Page page) throws CommonException{
		
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		List<Order> orderList =  orderService.getHistoryPaidOrderAtMercury(appId, contractNo, historyPaidType, page.getBeginIndex(), page.getMaxResultRecords());
		
		page.calculate(orderList.size());
		
		return orderList.size() > page.getEveryPage() ? orderList.subList(0, page.getEveryPage()) : orderList;
	}

	//TODO TRY CATCH
	
	@Override
	public List<AuthorisedBillSketch> getTodayPaidBill(String appId,
			String particalUniqueId, Page page) throws CommonException {
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		logger.info("begin to get the today paid bills with appId["+appId+"],begin["+begin+"],max=["+max+"] in the mercury.");
		App app = appService.getApp(appId);
		List<String> orderNoList = transactionRecordService.getDistinctOrderNoList(app, TransactionRecordStatus.PAID, new Date());
		if (CollectionUtils.isEmpty(orderNoList)){
			return Collections.EMPTY_LIST;
		}
		List<Order> orderList = orderService.getOrderByOrderNoFromTransactionRecord(app, orderNoList, begin, max);
		
		if (CollectionUtils.isEmpty(orderList)){
			return Collections.EMPTY_LIST;
		}
		List<AuthorisedBillSketch> authorisedBillSketchList = authorisedBillSketchService.convertOrderToAuthoriseBillSketch(orderList);
		
		if (CollectionUtils.isEmpty(authorisedBillSketchList)){
			return Collections.EMPTY_LIST;
		}
		page.calculate(authorisedBillSketchList.size());
		
		return authorisedBillSketchList.size() > page.getEveryPage() ? authorisedBillSketchList.subList(0, page.getEveryPage()) : authorisedBillSketchList;
	}

	@Override
	public List<AuthorisedBillSketch> getOutstandingBills(String appId,
			String particalUniqueId, Page page) throws CommonException {
		
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		
		List<Order> orderList = orderService.getOutstandingPaidOrder(appId, begin, max);
		
		if (orderList == null || orderList.size()==0){
			return Collections.EMPTY_LIST;
		}
		List<AuthorisedBillSketch> authorisedBillSketchList = authorisedBillSketchService.convertOrderToAuthoriseBillSketch(orderList);
		
		page.calculate(authorisedBillSketchList.size());
		
		return authorisedBillSketchList.size() > page.getEveryPage() ? authorisedBillSketchList.subList(0, page.getEveryPage()) : authorisedBillSketchList;
	}

	@Override
	public List<TransactionRecordSketch> getTransactionRecord(String appId,
			String particalUniqueId, List<String> billIds)
			throws CommonException {
		// TODO Auto-generated method stub
		return Collections.EMPTY_LIST;
	}

	@Override
	public boolean confirmTransactionRecord(String appId,
			String particalUniqueId, List<String> uniqueTransactionIds)
			throws CommonException {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public List<AuthorisedBillSketch> getOverPaymentDateBills(String appId,
			String particalUniqueId, Page page) throws CommonException {
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		List<Order> orderList = orderService.getUnpaidUnclearedOrderBeforeSomeDay(appId, new Date(), begin, max);
		
		if (orderList == null || orderList.size()==0){
			return Collections.EMPTY_LIST;
		}
		List<AuthorisedBillSketch> authorisedBillSketchList = authorisedBillSketchService.convertOrderToAuthoriseBillSketch(orderList);
		
		page.calculate(authorisedBillSketchList.size());
		
		return authorisedBillSketchList.size() > page.getEveryPage() ? authorisedBillSketchList.subList(0, page.getEveryPage()) : authorisedBillSketchList;
	}

	@Override
	public List<AuthorisedBillSketch> getNotReachPaymentDateBills(String appId,
			String particalUniqueId, Page page) throws CommonException {
		
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}

		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		List<Order> orderList = orderService.getUnpaidUnclearedOrderAfterSomeDay(appId, new Date(), begin, max);
		
		if (orderList == null || orderList.size()==0){
			return Collections.EMPTY_LIST;
		}
		List<AuthorisedBillSketch> authorisedBillSketchList = authorisedBillSketchService.convertOrderToAuthoriseBillSketch(orderList);
		
		page.calculate(authorisedBillSketchList.size());
		
		return authorisedBillSketchList.size() > page.getEveryPage() ? authorisedBillSketchList.subList(0, page.getEveryPage()) : authorisedBillSketchList;
	}

	@Override
	public ReceivablesBrief getReceivablesBrief(String appId,
			String particalUniqueId) throws CommonException {
		logger.info("begin to get receivables statis with param appId["+appId+"]");
		//TODO　remove exception?
		try {
			App app = appService.getApp(appId);
			
			int paidTodayBillsCount =  transactionRecordService.getDistinctTransactionCount(app, TransactionRecordStatus.PAID, new Date());
			
			int todayUnpaidUnclearedOrdersCount =  orderService.getUnpaidUnclearedOrderCountAtSomeDay(appId, new Date());
			
			int outstandingBillsCount =  orderService.getOutstandingPaidOrderCount(appId);
			
			int overPaymentDateBillsCount =  orderService.getUnpaidUnclearedOrderCountBeforeSomeDay(appId, new Date());;
			
			int notReachPaymentDateBillsCount =  orderService.getUnpaidUnclearedOrderCountAfterSomeDay(appId, new Date());
			
			ReceivablesBrief receivablesStatis = new ReceivablesBrief(paidTodayBillsCount, todayUnpaidUnclearedOrdersCount, 0, outstandingBillsCount, 0, notReachPaymentDateBillsCount, overPaymentDateBillsCount);
			
			MercuryReceivableHandlerImpl.logger.info("receivablesStatis:" + receivablesStatis);
			
			return receivablesStatis;
			
		} catch (Exception e) {
			
			logger.info("get the receivable statis error : " + e.getMessage());
			
			throw new CommonException(GeneralErrorCode.ERROR_SYSTEM);
		}
	}

	@Override
	public List<AuthorisedBillSketch> getTodayUnpaidOutstandingBill(
			String appId, String particalUniqueId, Page page)
			throws CommonException {
		if(org.springframework.util.StringUtils.isEmpty(appId)){
			
			throw new CommonException(GlobalSpec4Earth.ERROR_EMPTY_APPID);
		}
		
		int begin = page.getBeginIndex();
		
		int max = page.getMaxResultRecords();
		
		if(begin < 0 || max < 0 ){
			
			throw new CommonException(ErrorCode4AutorisedBillSketch.ERROR_BEGIN_OR_MAX_INVALID);
		}
		List<Order> orderList = orderService.getUnpaidUnclearedOrderAtSomeDay(appId, new Date(), begin, max);
		
		if (orderList == null || orderList.size()==0){
			return Collections.EMPTY_LIST;
		}
		List<AuthorisedBillSketch> authorisedBillSketchList = authorisedBillSketchService.convertOrderToAuthoriseBillSketch(orderList);
		
		page.calculate(authorisedBillSketchList.size());
		
		return authorisedBillSketchList.size() > page.getEveryPage() ? authorisedBillSketchList.subList(0, page.getEveryPage()) : authorisedBillSketchList;
	}

	@Override
	public int getHistoryPaidOrderCount(String appId, String particalUniqueId,
			HistoryPaidType historyPaidType) {
		return orderService.getHistoryPaidOrderCountAtMercury(appId, historyPaidType);
	}


}
